﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="KFast.cs" company="">
//   
// </copyright>
// <summary>
//   The k fast.
// </summary>
// --------------------------------------------------------------------------------------------------------------------


using System;
using Systemathics.FrameWork;

namespace Systemathics.Indicators
{

    [Serializable]
    public sealed class KFast : Indicator
    {
        private readonly BarSeries barseries;
        private readonly QuoteSeries quoteseries;
        private readonly TradeSeries tradeseries;

        public int Length { get; private set; }

        public KFast(Instrument instr, Data dt, BarType bt, int value, int length) : base(instr, dt, bt, value)
        {
            Length = length;
            switch (dt)
            {
                case Data.Quote:
                    quoteseries = new QuoteSeries("KFast");
                    break;
                case Data.Trade:
                    tradeseries = new TradeSeries("KFast");
                    break;
                case Data.Bar:
                    barseries = new BarSeries("KFast");
                    break;
            }
        }

        protected override void Calculate(object price)
        {
            if (price is Bar)
            {
                var bar = price as Bar;
                if (bar.High != Decimal.Zero && bar.Low != Decimal.Zero && bar.Close != Decimal.Zero)
                    Calculate(bar);
            }
            else if (price is Quote)
            {
                var quote = price as Quote;
                if (quote.Mid != Decimal.Zero)
                    Calculate(quote);
            }
            else
            {
                var trade = price as Trade;
                if (trade.Price != Decimal.Zero)
                    Calculate(trade);
            }
        }

        private void Calculate(Bar bar)
        {
            barseries.Add(bar);
            if (barseries.Count >= Length)
            {
                Add(bar.BeginTime, 100*((bar.Close - barseries.LowestLow(Length))/ (barseries.HighestHigh(Length) - barseries.LowestLow(Length))));
                IndicatorCalculated(this);
            }
        }

        private void Calculate(Quote quote)
        {
            quoteseries.Add(quote);
            if (quoteseries.Count >= Length)
            {
                Add(quote.Time, 100*((quote.Mid - quoteseries.Low(Length))/(quoteseries.High(Length) - quoteseries.Low(Length))));
                IndicatorCalculated(this);
            }
        }

        private void Calculate(Trade trade)
        {
            tradeseries.Add(trade);
            if (quoteseries.Count >= Length)
            {
                Add(trade.Time, 100*((trade.Price - tradeseries.Low(Length))/(tradeseries.High(Length) - tradeseries.Low(Length))));
                IndicatorCalculated(this);
            }
        }
    }
}